<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Document</title>
</head>

<body>
  <script>

    {
      /* 
      在 Vue 3 中，DOM Diff 算法使用了最长递增子序列 (LIS) 算法来优化更新过程。这种优化可以减少不必要的 DOM 操作，提高性能。

最长递增子序列是一个在一个序列中查找一个最长的子序列，使得子序列中的所有元素按照顺序递增。在 Vue 3 的 DOM Diff 算法中，使用最长递增子序列来确定哪些节点应该被移动，而不是直接删除和重新创建节点。

在比较两个节点列表时，DOM Diff 算法会根据节点的唯一标识符（例如：key）来判断节点是否相同。如果两个节点的 key 相同，则认为它们是相同的节点，不需要移动。如果两个节点的 key 不同，DOM Diff 算法会根据它们在列表中的位置和最长递增子序列算法来决定是否需要移动节点。

最长递增子序列算法会计算出两个序列中的最长递增子序列的索引，然后根据这些索引来判断哪些节点需要移动。通过这种方式，DOM Diff 算法可以最小化节点的移动和重新创建，从而提高了性能和效率。

需要注意的是，在使用 Vue 3 的时候，你不需要手动处理最长递增子序列算法。Vue 3 的响应式系统会自动应用这种优化，以提高组件更新的性能。你只需要正确地设置节点的 key 属性，Vue 3 就会在内部使用最长递增子序列算法来进行优化。


js 最长递增子序列算法：
JavaScript 中也可以使用动态规划算法来解决最长递增子序列问题。以下是一个使用动态规划算法求解最长递增子序列的 JavaScript 示例代码：
function lengthOfLIS(nums) {
  const n = nums.length;
  const dp = new Array(n).fill(1);
  let maxLen = 1;

  for (let i = 1; i < n; i++) {
    for (let j = 0; j < i; j++) {
      if (nums[i] > nums[j]) {
        dp[i] = Math.max(dp[i], dp[j] + 1);
      }
    }

    maxLen = Math.max(maxLen, dp[i]);
  }

  return maxLen;
}
使用这个算法，你可以得到给定序列的最长递增子序列的长度。如果你需要获取最长递增子序列本身，你可以根据 dp 数组的值进行回溯。
例如，对于输入数组 [10, 9, 2, 5, 3, 7, 101, 18]，lengthOfLIS 函数将返回 4，表示最长递增子序列的长度为 4。在这个示例中，最长递增子序列是 [2, 5, 7, 101]。
请注意，这只是解决最长递增子序列问题的一种方法。在实际应用中，还可以使用其他算法或优化来解决该问题。




    
    
    */
    }


    {
      /* 
        在 Vue 3 中，v-if 和 v-for 的优先级确实有所变化。

在 Vue 2 中，当一个元素同时存在 v-if 和 v-for 指令时，v-for 会拥有更高的优先级。这意味着 v-for 会先被解析，然后再应用 v-if 条件。这可能导致一些不必要的循环遍历，特别是在列表中的元素很多时。

而在 Vue 3 中，v-if 指令现在拥有更高的优先级。这意味着 v-if 的条件会先被解析，然后再进行 v-for 循环遍历。这样做的目的是为了提高性能，避免不必要的循环遍历。

这种变化使得在 Vue 3 中，你可以更自由地使用 v-if 和 v-for 指令，而不必担心可能出现的性能问题。例如，你可以在同一个元素上同时使用 v-if 和 v-for，并且 v-if 的条件可以根据需要动态改变，而不会导致额外的循环遍历。

需要注意的是，虽然在 Vue 3 中 v-if 和 v-for 的优先级有所变化，但仍然建议在性能要求较高的情况下尽量避免在同一个元素上同时使用这两个指令，以减少不必要的计算和渲染开销。
      */
    }

    /*
      使用 WeakMap 有以下几个好处：
      
      避免内存泄漏：WeakMap 是一种弱引用的数据结构，它不会阻止垃圾回收器回收键（键是对象）所占用的内存。当键对象被垃圾回收时，WeakMap 会自动删除与该键相关联的值，从而避免内存泄漏的问题。
      
      隐藏数据结构：WeakMap 的键只能是对象，而且对外部不可见。这使得 WeakMap 适用于存储敏感信息或隐藏实现细节。只有持有对应键的引用的代码才能访问到 WeakMap 中的值，从而提供了一定程度的数据安全性。
      
      高效查找：由于 WeakMap 是使用哈希表实现的，它提供了 O(1) 时间复杂度的键值对查找操作。这使得 WeakMap 在需要频繁查找键值对的场景下具有高效性能。
      
      支持对象引用作为键：WeakMap 可以使用任意对象作为键，而不仅限于基本类型（如字符串、数字等）。这使得 WeakMap 在需要使用对象引用作为键的情况下非常有用，例如在实现缓存、数据关联等场景中。
      
      需要注意的是，由于 WeakMap 的键只能是对象，而且不支持遍历操作，因此它并不适用于存储一组键值对，而是更适合用于存储一些与对象相关联的附加信息或状态。
      */
    // Performs a deep clone of an object using WeakMap.
    // This function recursively clones all properties of the object, including nested objects and arrays.
    // It uses a WeakMap to keep track of cloned objects to avoid infinite recursion in case of circular references.

    /**
     * @param {Object} obj - The object to be cloned.
     * @param {WeakMap} cloneMap - A WeakMap to keep track of cloned objects.
     * @returns {Object} - The cloned object.
     */
    function deepClone(obj, cloneMap = new WeakMap()) {
      // If the object is null or not an object, return it as is
      if (obj === null || typeof obj !== 'object') {
        return obj;
      }

      // Check if the object has already been cloned
      if (cloneMap.has(obj)) {
        return cloneMap.get(obj);
      }

      // Create a new object with the same prototype as the original object
      const clonedObj = Object.create(Object.getPrototypeOf(obj));

      // Add the cloned object to the cloneMap
      cloneMap.set(obj, clonedObj);

      // Clone each property of the original object
      for (let key in obj) {
        if (obj.hasOwnProperty(key)) {
          clonedObj[key] = deepClone(obj[key], cloneMap);
        }
      }

      return clonedObj;
    }
    // Test cases for the deepClone function

    // Test case 1: Cloning a simple object
    const obj1 = { name: 'John', age: 30 };
    const clonedObj1 = deepClone(obj1);
    console.log(clonedObj1); // { name: 'John', age: 30 }
    console.log(clonedObj1 === obj1); // false

    // Test case 2: Cloning an object with nested objects and arrays
    const obj2 = {
      name: 'Alice',
      age: 25,
      address: {
        city: 'New York',
        country: 'USA',
      },
      hobbies: ['reading', 'painting'],
    };
    const clonedObj2 = deepClone(obj2);
    console.log(clonedObj2);
    /* 
  {
    name: 'Alice',
    age: 25,
    address: { city: 'New York', country: 'USA' },
    hobbies: ['reading', 'painting']
  }
  */
    console.log(clonedObj2 === obj2); // false

    // Test case 3: Cloning an object with circular reference
    const obj3 = { foo: 'bar' };
    obj3.self = obj3;
    const clonedObj3 = deepClone(obj3);
    console.log(clonedObj3); // { foo: 'bar', self: [Circular] }
    console.log(clonedObj3 === obj3); // false

    // Test case 4: Cloning an object with symbol properties
    const sym = Symbol('test');
    const obj4 = { [sym]: 'symbol' };
    const clonedObj4 = deepClone(obj4);
    console.log(clonedObj4); // { [Symbol(test)]: 'symbol' }
    console.log(clonedObj4 === obj4); // false

    {
      function addWithoutFloat(num1, num2) {
        const multiplier = Math.pow(10, 10); // 10的10次方，根据需要调整精度
        const result =
          Math.round(num1 * multiplier) + Math.round(num2 * multiplier);
        return result / multiplier;
      }

      console.log(addWithoutFloat(0.1, 0.2)); // 输出: 0.3
      console.log(addWithoutFloat(1234567.01, 1234567.02)); // 输出: 0.3

      // const symbol1 = Symbol('symbol');
      // const symbol2 = Symbol('symbol');

      // const set = new Set();
      // set.add(symbol1);
      // set.add(symbol2);

      // console.log(set);  // 输出: 2
      // console.log(set.size);  // 输出: 2
      // console.log(set.has(symbol1));  // 输出: true
      // console.log(set.has(symbol2));  // 输出: true
    }
  </script>
</body>

</html>